//
// Created by Dinger on 2021/9/18.
//

#ifndef FUNDAMENTALS_OF_COMPILING_CONVERSION_FORM_H
#define FUNDAMENTALS_OF_COMPILING_CONVERSION_FORM_H

#include"stdafx.h"

using namespace std;

/**
 * 转换表
 */
class ConversionForm {
private:
    //表体
    vector<vector<int>> _conversionForm;
    //NAF表体
    vector<vector<vector<int>>> _conversionFormNFA;
    //词法字符
    vector<char> _symbols;
    //NFA词法字符
    vector<char> _symbolsNFA;
    //状态集合
    vector<int> _states;
    //NFA状态集合
    vector<int> _statesNFA;
    //终态集合
    vector<int> _terminalStates;
    //NFA终态集合
    vector<int> _terminalStatesNFA;
    //行
    int _row;
    //列
    int _col;
    //l是否表示字母整体
    bool _letterFlag;
    //是否为DFA
    bool _isDFA;
    //空边位置
    int _spacePosition;

    /**
     * 读取文件
     * @param fileName
     */
    void readFile(string fileName);

    /**
     * 读取NFA文件
     * @param fileName
     */
    void readFileNFA(string fileName);

    /**
     * 从字符串中找出状态集合
     * @param inputString 输入字符串
     * @return 状态集合
     */
    vector<int> divideStates(string inputString);

    /**
     * 从字符串中找出状态
     * @param inputString 输入字符串
     * @return 状态
     */
    int findStates(string inputString);

    /**
     * NFA转为DFA
     */
    void NFA2DFA();

    /**
     * 求单个状态的闭包
     * @param state 状态
     * @param closure 闭包集合
     */
    void findClosure(int state, set<int> &closure);

    /**
     * 求状态集合的闭包
     * @param states 状态集合
     * @return 闭包集合
     */
    set<int> findClosure(set<int> states);

    /**
     * 找到没有被标记的状态
     * @param tags 标记集合
     * @return 状态
     */
    int findNoMarkedState(vector<bool> tags);

    /**
     * 求Move
     * @param closure 闭包集合
     * @param symbol 符号
     * @return 闭包集合
     */
    set<int> findMove(set<int> closure, char symbol);

    /**
     * 在所有闭包集中搜索某个闭包
     * @param closure 目标闭包
     * @param allClosures 所有闭包集
     * @return 找到——返回下标，未找到——返回-1
     */
    int findClosureInAllClosures(set<int> closure, vector<set<int>> allClosures);

    /**
     * 判断两个闭包是否相同
     * @param closure1 闭包1
     * @param closure2 闭包2
     * @return true-相同，false-不同
     */
    bool isEqual(set<int> closure1, set<int> closure2);

    /**
     * 写进文件
     * @param fileName 文件名
     */
    void writeInFile(string fileName);

    /**
     * 找新的终态
     * @param closure 闭包集合
     * @param k 状态
     */
    void findNewTerminalState(set<int> closure, int k);

    /**
     * DFA最小化
     */
    void minimizeDFA();

    /**
     * 最小化过程
     * @param statesGroups 状态分类集合
     * @param statesGroupNumber 状态分类集合下标
     * @param symbolNumber 符号位置
     */
    void minimizeProcess(vector<vector<int>> &statesGroups, int &statesGroupNumber, int symbolNumber);

    /**
     * 在一个符号过程里给状态分类
     * @param statesGroups 状态分类集合
     * @param oneStatesGroup 一个分类组
     * @param otherGroups 其他的组
     * @param resultStatesGroups 分类结果
     * @param symbol 符号
     * @return 是否有分类发生
     */
    bool classifyStatesInOneSymbol(vector<vector<int>> statesGroups, vector<int> oneStatesGroup,
                                   vector<vector<int>> otherGroups, vector<vector<int>> &resultStatesGroups,
                                   char symbol);

    /**
     * 判断一个状态是否在一个状态集里
     * @param states 状态集
     * @param state 状态
     * @return true-在，false-不在
     */
    bool isInStates(vector<int> states, int state);

    /**
     * 重新制作转换表
     * @param statesGroups 所有状态组
     */
    void remakeForm(vector<vector<int>> statesGroups);

    /**
     * 找其他的状态组
     * @param statesGroups 所有的状态组
     * @param i 目前状态组下标
     * @return 其他的状态组
     */
    vector<vector<int>> findOtherGroups(vector<vector<int>> statesGroups, int i);

    /**
     * 做一个新状态的map
     * @param statesGroups 所有状态组
     * @return 新状态的map
     */
    map<int, int> makeNewStateMap(vector<vector<int>> statesGroups);

public:
    ConversionForm();

    ConversionForm(string fileName, bool letterFlag);

    ConversionForm(string fileName, bool letterFlag, bool isDFA);

    vector<vector<int>> getConversionForm() {
        return _conversionForm;
    }

    vector<char> getSymbols() {
        return _symbols;
    }

    bool getLetterFlag() {
        return _letterFlag;
    }

    int getRow() {
        return _row;
    }

    int getCol() {
        return _col;
    }

    vector<int> getStates() {
        return _states;
    }

    vector<int> getTerminalStates() {
        return _terminalStates;
    }

    void setConversionForm(vector<vector<int>> conversionForm) {
        _conversionForm = conversionForm;
    }

    void setSymbols(vector<char> symbols) {
        _symbols = symbols;
    }

    void setLetterFlag(bool letterFlag) {
        _letterFlag = letterFlag;
    }

    void setRow(int row) {
        _row = row;
    }

    void setCol(int col) {
        _col = col;
    }

    void setStates(vector<int> states) {
        _states = states;
    }

    void setTerminalStates(vector<int> terminalStates) {
        _terminalStates = terminalStates;
    }

    /**
     * 找字符位置
     * @param symbol 字符
     * @return 位置
     */
    int findSymbolPosition(char symbol);

    bool isTerminal(int state);
};

#endif //FUNDAMENTALS_OF_COMPILING_CONVERSION_FORM_H
